package top.ajunnihao.core.web.controller;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import top.ajunnihao.core.entity.Order;
import top.ajunnihao.core.entity.SiteScenic;
import top.ajunnihao.core.entity.SiteTicket;
import top.ajunnihao.core.service.OrderService;
import top.ajunnihao.core.service.SiteScenicService;
import top.ajunnihao.core.service.SiteTicketService;
import top.ajunnihao.core.util.resp.JResp;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 景点前端控制器
 * </p>
 */
@Controller
public class SiteScenicController {

    private static final Integer SIZE = 4;
    private static final Integer ADMIN_SIZE = 7;

    @Autowired
    private SiteScenicService siteScenicService;
    @Autowired
    private SiteTicketService siteTicketService;
    @Autowired
    private OrderService orderService;

    @GetMapping({"", "/", "/index"})
    public String siteList(Model model) {
        List<SiteScenic> siteScenicList = siteScenicService.list(
            Wrappers.<SiteScenic>lambdaQuery().last("LIMIT 4")
        );
        model.addAttribute("siteList", siteScenicList);
        return "index";
    }

    @GetMapping("/site/list")
    public String siteScenicList(Integer page, Model model) {
        if (page == null) {
            page = 1;
        }
        IPage<SiteScenic> sitePage = siteScenicService.page(
            new Page<>(page, SIZE),
            Wrappers.<SiteScenic>lambdaQuery()
                .orderByDesc(SiteScenic::getSiteId)
        );
        model.addAttribute("sitePage", sitePage);
        return "site-scenics";
    }

    @GetMapping("/site/detail/{id}")
    public String siteDetail(@PathVariable("id") Long id, Model model) {
        // 景点信息
        SiteScenic siteScenic = siteScenicService.getById(id);
        model.addAttribute("siteScenic", siteScenic);
        // 门票信息
        SiteTicket siteTicket = siteTicketService.getOne(
            Wrappers.<SiteTicket>lambdaQuery().eq(SiteTicket::getSiteId, id)
        );
        model.addAttribute("siteTicket", siteTicket);
        return "site-detail";
    }

    @GetMapping("/admin/sites")
    public String adminListSite(Integer page, Model model) {
        if (page == null) {
            page = 1;
        }
        IPage<SiteScenic> sitePage = siteScenicService.page(
            new Page<>(page, ADMIN_SIZE),
            Wrappers.<SiteScenic>lambdaQuery()
                .orderByDesc(SiteScenic::getSiteId)
        );
        model.addAttribute("sitePage", sitePage);
        System.out.println(JResp.ok(sitePage));
        return "admin/site-list";
    }

    @GetMapping("/admin/site/search")
    public String adminSearchSite(Integer page, String site, Model model) {
        if (page == null) {
            page = 1;
        }
        IPage<SiteScenic> sitePage = siteScenicService.page(
            new Page<>(page, ADMIN_SIZE),
            Wrappers.<SiteScenic>lambdaQuery()
                .like(SiteScenic::getSiteName, site)
                .orderByDesc(SiteScenic::getSiteId)
        );
        if (CollUtil.isEmpty(sitePage.getRecords())) {
            model.addAttribute("searchMsg", "无此记录");
        }
        model.addAttribute("sitePage", sitePage);
        // System.out.println(JResp.ok(sitePage));
        return "admin/site-list";
    }

    @PostMapping("/admin/site/deleteSite.do")
    @ResponseBody
    public Object adminDeleteSite(@RequestBody JSONObject jReq) {
        long siteId = jReq.getLongValue("siteId");
        // 对应的门票和订单也要删除
        SiteTicket siteTicket = siteTicketService.getOne(
            Wrappers.<SiteTicket>lambdaQuery()
                .eq(SiteTicket::getSiteId, siteId)
        );
        Order order = orderService.getOne(
            Wrappers.<Order>lambdaQuery()
                .eq(Order::getTicketId, siteTicket.getTicketId())
        );

        // 删除景点、门票、订单
        boolean flag1 = siteScenicService.removeById(siteId);
        boolean flag2 = siteTicketService.removeById(siteTicket.getTicketId());
        boolean flag3 = orderService.removeById(order.getOrderId());

        if (!flag1 || !flag2 || !flag3) {
            return JResp.error("删除失败，景点 ID = " + siteId);
        }
        return JResp.ok("删除成功，景点 ID = " + siteId);
    }

    @PostMapping("/admin/site/findSiteById.do")
    @ResponseBody
    public Object adminFindSiteById(@RequestBody JSONObject jReq) {
        long siteId = jReq.getLongValue("siteId");
        SiteScenic siteScenic = siteScenicService.getById(siteId);
        SiteTicket siteTicket = siteTicketService.getOne(
            Wrappers.<SiteTicket>lambdaQuery()
                .eq(SiteTicket::getSiteId, siteId)
        );
        if (siteScenic == null || siteTicket == null) {
            return JResp.error("查询失败");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("siteScenic", siteScenic);
        map.put("siteTicket", siteTicket);
        return JResp.ok(map, "查询成功");
    }

    @PostMapping("/admin/site/updateSite.do")
    @ResponseBody
    public Object adminUpdateSite(@RequestBody JSONObject jReq) {
        // 更新景点
        SiteScenic siteScenic = jReq.getObject("site", SiteScenic.class);
        boolean flag1 = siteScenicService.updateById(siteScenic);
        // 根据 siteId 找到对应的票，修改它
        SiteTicket siteTicket = jReq.getObject("siteTicket", SiteTicket.class);
        SiteTicket ticket = siteTicketService.getOne(
            Wrappers.<SiteTicket>lambdaQuery()
                .eq(SiteTicket::getSiteId, siteScenic.getSiteId())
        );
        siteTicket.setTicketId(ticket.getTicketId()); // 给要修改的票设置它的 ticketId
        boolean flag2 = siteTicketService.updateById(siteTicket);
        if (!flag1 || !flag2) {
            return JResp.error("更新失败");
        }
        return JResp.ok(siteScenic, "更新成功");
    }

    @PostMapping("/admin/site/addSite.do")
    @ResponseBody
    public Object adminAddSite(@RequestBody JSONObject jReq) {
        // 保存景点
        SiteScenic siteScenic = jReq.getObject("site", SiteScenic.class);
        boolean flag1 = siteScenicService.save(siteScenic);
        // 保存门票
        SiteTicket siteTicket = jReq.getObject("siteTicket", SiteTicket.class);
        siteTicket.setSiteId(siteScenic.getSiteId());  // 设置票的 id
        boolean flag2 = siteTicketService.save(siteTicket);
        if (!flag1 || !flag2) {
            return JResp.error("添加失败");
        }
        return JResp.ok(siteScenic, "添加成功");
    }

    @PostMapping("/admin/site/imgUpload.do")
    @ResponseBody
    public Object attachmentUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        // 文件上传目标目录
        String uploadPath = "D:/travelFile/";

        // 获取上传文件原始名称
        String filename = file.getOriginalFilename();
        // 给文件取一个唯一名称
        assert filename != null;
        filename = randomName(filename);

        // 完成上传文件
        Map<String, Object> resultMap = new HashMap<>();
        try {
            file.transferTo(new File(uploadPath, filename));
            resultMap.put("url", "/upload/" + filename);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return JResp.ok(resultMap, "上传成功");
    }

    /**
     * 给文件取一个唯一名称
     *
     * @param filename 文件名称
     * @return 唯一文件名称
     */
    private String randomName(String filename) {
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String timeStr = DateTimeFormatter.ofPattern("yyyyMMdd").format(LocalDate.now());
        return timeStr + "_" + uuid + filename.substring(filename.lastIndexOf('.'));
    }

}
